www.gusucode.com > VC++ 密码探测器 > VC++ 密码探测器/gusucode/PwdSpyHk/PwdSpyHk.cpp

    // If you're compiling this using VC++5 you must define STRICT.
// If you're using VC++6 it works without this define, so
// obviously Microsoft changed the header files to define it
// for you.  For more info see the following article in the MSDN:
//   TN012: Using MFC with Windows 3.1 Robustness Features
#ifndef STRICT
#define STRICT 1
#endif

#include <windows.h>
#include <tchar.h>
#include <crtdbg.h>

#include "PwdSpyHk.h"
#include "IPC.h"

// Global variables
static HHOOK g_hHook = NULL;				// 钩子句柄
static DWORD g_dwThreadId = 0;				// 被挂钩的线程
static HINSTANCE g_hinstDLL = NULL;			// 该DLL的句柄
static CIPC g_obIPC;						// 用来保护共享的资源,连接主进程和被钩进程的钩子函数

static UINT g_wmScanPassword = RegisterWindowMessage(IPC_CUSTOM_MSG);

// Since this DLL is loaded by both PasswordSpy and the remote (or hooked) process,
// each function in this DLL is listed which of the two processes calls that function.

//***********************************************
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	// 该DLL被两个进程调用

	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		// DLL映射进进程地址空间
		g_hinstDLL = hinstDLL;

		// This call disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH
		// messages.  DllMain should not get called with those messages.
		DisableThreadLibraryCalls(GetModuleHandle(PWDSPY_HOOK_DLL));
		break;
	case DLL_THREAD_ATTACH:
		// 创建线程
		break;
	case DLL_THREAD_DETACH:
		// 存在的线程.
		break;
	case DLL_PROCESS_DETACH:
		// DLL从进程中卸载
		break;
	}
	return TRUE;
}

//***********************************************
bool WINAPI InstallHook(const DWORD dwThreadId)
{
	// 该函数仅被PasswordSpy调用

	_ASSERTE(dwThreadId);

	bool bSuccess = false;

	try
	{
		// 是否想挂钩的线程已经被钩住了
		if(g_dwThreadId == dwThreadId)
			return true;

		// 如果已经挂钩在另一个线程上,先把钩子解除
		if(g_dwThreadId != dwThreadId && g_hHook != NULL)
			RemoveHook();

		//存储挂钩的线程句柄 
		if((g_dwThreadId = dwThreadId) != 0)
		{
			// 锁住共享的资源
			g_obIPC.Lock();
			g_obIPC.CreateIPCMMF();
            //安装钩子
			g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDLL, g_dwThreadId);
			if(g_hHook != NULL)
			{
				// 进入共享资源,存储钩子句柄
				DWORD dwData = (DWORD)g_hHook;
				g_obIPC.WriteIPCMMF((LPBYTE)&dwData, sizeof(dwData));
				bSuccess = true;
				// 发一个消息到被钩线程队列,强迫调用钩子程序
				PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
			}
		}
	}
	catch(...) {}

	// 解开共享的资源
	g_obIPC.Unlock();

	return bSuccess;
}

//***********************************************
bool WINAPI RemoveHook(void)
{
	// 该函数仅被PasswordSpy调用

	bool bSuccess = false;

	try
	{
		if(g_hHook != NULL)
		{
			//卸载钩子
			bSuccess = UnhookWindowsHookEx(g_hHook) ? true : false;
			g_hHook = NULL;
			g_dwThreadId = 0;
		}
	}
	catch(...) {}

	return bSuccess;
}

//***********************************************
bool WINAPI ScanPassword(const HWND hWnd, const HWND hPwdSpyWnd) //扫描密码
{
	// 该函数仅被PasswordSpy调用

	bool bSuccess = false;

	try
	{
		if(g_dwThreadId != 0 && hWnd != NULL && hPwdSpyWnd != NULL)
		{
			//向被钩线程的子窗口发消息
			PostThreadMessage(g_dwThreadId, g_wmScanPassword, (WPARAM)hWnd, (LPARAM)hPwdSpyWnd);
			bSuccess = true;
		}
	}
	catch(...) {}

	return bSuccess;
}

//***********************************************
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	// 该函数仅被被钩的进程调用

	try
	{
		if(g_hHook == NULL)
		{	// 从共享区读出钩子句柄
			DWORD dwData = 0, dwSize = sizeof(dwData);
			g_obIPC.Lock();
			g_obIPC.OpenIPCMMF();
			g_obIPC.ReadIPCMMF((LPBYTE)&dwData, dwSize);
			g_obIPC.Unlock();

			g_hHook = (HHOOK)dwData;
		}

		if(nCode >= 0)
		{
			HWND hWnd = NULL;		// 拥有密码的窗口句柄,在被钩线程上
			HWND hPwdSpyWnd = NULL;	// PasswordSpy 窗口句柄, so we can SendMessage back
			MSG *pMsg = (MSG*)lParam;

			// 是否是我们自己发出的消息
			if(pMsg->message == g_wmScanPassword)
			{
				hWnd = (HWND)pMsg->wParam;
				hPwdSpyWnd = (HWND)pMsg->lParam;

				ExtractPassword(hWnd, hPwdSpyWnd);//得到密码
			}
		}
	}
	catch(...) {}

	// Always call the next hook in the chain
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

//***********************************************
void ExtractPassword(const HWND hWnd, const HWND hPwdSpyWnd)
{
	// 该函数仅被被钩的进程调用

	_ASSERTE(hWnd);
	_ASSERTE(hPwdSpyWnd);

	try
	{
		TCHAR szBuffer[256] = {_T('\0')};
		//被钩进程得到自己某个窗口的内容
		SendMessage(hWnd, WM_GETTEXT, sizeof(szBuffer) / sizeof(TCHAR), (LPARAM)szBuffer);

		// 利用WM_COPYDATA把密码发送回PasswordSpy
		COPYDATASTRUCT cds = {0};
		cds.dwData = (DWORD)hWnd;
		cds.cbData = (lstrlen(szBuffer) + 1) * sizeof(TCHAR);
		cds.lpData = szBuffer;
        //将得到的密码返回给hPwdSpy窗口
		SendMessage(hPwdSpyWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
	}
	catch(...) {}
}